/*
 * orderinfo_transfer.c
 *
 *  Created on: 2013-2-15
 *      Author: panqiuhui
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <pthread.h>

#include "../head/common_struct/orderinfo.h"
#include "../head/common_struct/orderlist.h"
#include "../head/communicate_with_client/orderinfo_transfer.h"
#include "../head/dao/orderinfo_dao.h"

//负责接受与火车相关的请求的线程的启动函数
void *orderinfo_thread_function(void *arg) {
	//启动线程
	int port = *(int *) arg;

	int server_socketfd, client_socketfd;
	int server_len, client_len;
	struct sockaddr_in server_address;
	struct sockaddr_in client_address;
	int result;
	int maxfd;
	fd_set readfds, tempfds;

	server_socketfd = socket(AF_INET, SOCK_STREAM, 0);

	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr = htonl(INADDR_ANY );
	server_address.sin_port = htons(port);
	server_len = sizeof(server_address);

	bind(server_socketfd, (struct sockaddr *) &server_address, server_len);

	listen(server_socketfd, 5);

	FD_ZERO(&readfds);
	FD_SET(server_socketfd, &readfds);
	maxfd = server_socketfd;

	printf("orderinfo_thread start.\n");

	while (true) {
		int fd;
		int nread;

		tempfds = readfds;

		printf("orderinfo_thread server waiting\n");
		result = select(maxfd + 1, &tempfds, NULL, NULL, NULL );

		if (result < 1) {
			perror("orderinfo_transfer.c: error\n");
			break;
		}

		for (fd = 0; fd <= maxfd; fd++) {
			if (FD_ISSET(fd,&tempfds)) {
				if (fd == server_socketfd) {
					client_len = sizeof(client_address);
					client_socketfd = accept(server_socketfd,
							(struct sockaddr*) &client_address,
							(socklen_t*) &client_len);
					FD_SET(client_socketfd, &readfds);
					if (client_socketfd > maxfd) {
						maxfd = client_socketfd;
					}
					printf("orderinfo_thread add client on fd %d\n",
							client_socketfd);
				} else {
					ioctl(fd, FIONREAD, &nread);
					if (nread == 0) {
						close(fd);
						FD_CLR(fd, &readfds);
						printf("orderinfo_thread remove client in fd %d\n", fd);
					} else {
						struct orderinfo_request_type type;
						read(fd, &type, sizeof(type));
						switch (type.type) {
						case TYPE_SEARCH_ORDER: {
							struct orderinfo_search_request request;
							read(fd, &request, sizeof(request));
							OrderList orderlist; //声明链表
							InitializeList(&orderlist); //初始化链表
							bool search_result = true;
							search_result = search_order(&request, &orderlist);
							write(fd, &search_result, sizeof(search_result));
							if (search_result) {
								OrderNode *node = orderlist;
								bool islast = false;
								while (node != NULL ) {
									OrderItem item = node->item;
									write(fd, &item, sizeof(item));
									node = node->next;
									if (node == NULL ) {
										islast = true;
									}
									write(fd, &islast, sizeof(islast));
								}
							}
							EmptyTheList(&orderlist); //释放链表
							break;
						}
						case TYPE_REFUND_ORDER: {
							struct orderinfo_refund_request request;
							read(fd, &request, sizeof(request));
							OrderList orderlist; //声明链表
							InitializeList(&orderlist); //初始化链表
							bool islast = false;
							while (!islast) {
								OrderItem item;
								memset(&item, 0, sizeof(item));
								read(fd, &item, sizeof(item));
								AddItem(item, &orderlist);
								read(fd, &islast, sizeof(islast));
							}
							bool refund_result = true;
							refund_result = refund_order(&request, &orderlist);
							write(fd, &refund_result, sizeof(refund_result));
							EmptyTheList(&orderlist); //释放链表
							break;
						}
						default: {
							perror("orderinfo_thread request type error\n");
							break;
						}
						}
					}
				}
			}
		}
	}

	pthread_exit("orderinfo_thread exit failure!");
}
